﻿// src/crudOption/message/actions.js

/**
 * 仅使用 Pinia 的 hasAuth（(keys:string[]) => boolean）做权限校验
 *
 * 用法（页面 setup）：
 *
 *   import { createBuildNoticeActions } from '@/crudOption/message/actions'
 *
 *   const buildRowActions = createBuildNoticeActions({
 *
 *     fns: { openEditDialog, confirmHide, confirmShow, confirmSend, loadDel },
 *     denyStrategy: 'hide',  // 或 'disable'：未授权时显示但禁用
 *   })
 *
 *   // 模板：
 *   // <ActionBar :row="row" :max-inline="3" :actions="buildRowActions" />
 */

// ===== 业务状态判断：与页面逻辑一致 =====
const U = v => (v == null ? "" : String(v).toUpperCase());

function sendStatusOf(row) {
  // 后端：sendStatus ∈ { INIT, PROCESS, SUCCESS, FAIL }
  return U(row.sendStatus || row.status);
}
function showStatusOf(row) {
  // 后端：displayStatus ∈ { SHOW, HIDE }
  return U(row.displayStatus || row.showStatus || row.display);
}

const isSendFailed = row => sendStatusOf(row) === "FAIL" || sendStatusOf(row) === "INIT";
const isShown = row => showStatusOf(row) === "SHOW";
const isHidden = row => showStatusOf(row) === "HIDE";

// 可操作条件
const canHide = row => isShown(row); // 展示中 -> 隐藏
const canShow = row => isHidden(row); // 已隐藏 -> 展示
const canSend = row => {
  // 手动/失败 -> 发送
  const t = U(row.sendType); // NOW / MANUAL / TIMING
  return t === "MANUAL" || isSendFailed(row);
};

// ===== 只用 hasAuth 做校验 =====
/**
 * @param {Function} hasAuth  (keys:string[]) => boolean
 * @param {string|string[]|function|undefined|null} perm
 * @param {object} row
 */
function allowByPerm(hasAuth, perm, row) {
  // 没配置权限点 => 不受权限控制，直接放行
  if (!perm) return true;

  // 自定义函数（少数特殊场景）
  if (typeof perm === "function") {
    try {
      return !!perm(row);
    } catch {
      return false;
    }
  }

  // 字符串或数组 => 调用 hasAuth（任一命中即通过）
  const keys = Array.isArray(perm) ? perm : [perm];
  return typeof hasAuth === "function" ? !!hasAuth(keys) : false;
}

/**
 * 未授权处理：'hide'（默认）| 'disable'
 */
function applyDenyStrategy(action, denyStrategy) {
  if (denyStrategy === "disable") {
    return { ...action, disabled: true, onClick: undefined, danger: false, divided: false };
  }
  return null; // hide
}

// 核心：解析 hasAuth（支持注入；没传则尝试从 Pinia 获取）
function resolveHasAuth(passedHasAuth) {
  if (passedHasAuth) return passedHasAuth;
  try {
    const user = useUserInfoStore(); // ⚠️ 必须在 setup() 或激活的 Pinia 上下文里调用
    return user.hasAuth; // getters 返回的就是 (keys)=>boolean
  } catch (e) {
    console.warn("[notificationList] hasAuth 未传且 Pinia 未激活，默认视为无权限");
    return () => false;
  }
}

/**
 * 工厂：生成 (row)=>actions
 * @param {object} opts
 *  - hasAuth: (keys:string[])=>boolean       // 非必传：Pinia 的 hasAuth
 *  - fns: { openEditDialog, confirmHide, confirmShow, confirmSend, loadDel }
 *  - denyStrategy?: 'hide'|'disable'         // 默认 'hide'
 */
export function createBuildNoticeActions(opts = {}) {
  const hasAuth = resolveHasAuth(opts.hasAuth);
  const fns = opts.fns || {};
  const denyStrategy = opts.denyStrategy === "disable" ? "disable" : "hide";

  return function buildRowActions(row) {
    // 候选按钮：
    // 说明：perm 缺省 => 无权限限制；若需要受控，填入权限点字符串或数组
    const candidates = [
      {
        key: "edit",
        label: "编辑",
        order: 1,
        when: true,
        perm: PERMS.MESSAGE.MSG_CONTENT.UPDATE,
        onClick: () => fns.openEditDialog?.(row),
      },
      {
        key: "hide",
        label: "隐藏",
        order: 2,
        when: canHide(row),
        perm: PERMS.MESSAGE.MSG_CONTENT.ENABLE,
        onClick: () => fns.confirmHide?.(row),
      },
      {
        key: "show",
        label: "展示",
        order: 3,
        when: canShow(row),
        perm: PERMS.MESSAGE.MSG_CONTENT.ENABLE,
        onClick: () => fns.confirmShow?.(row),
      },
      {
        key: "send",
        label: sendStatusOf(row) === "FAIL" ? "重新发送" : "发送",
        order: 4,
        when: canSend(row),
        perm: PERMS.MESSAGE.MSG_CONTENT.SEND,
        onClick: () => fns.confirmSend?.(row),
      },
      {
        key: "del",
        label: "删除",
        order: 99,
        when: true,
        perm: PERMS.MESSAGE.MSG_CONTENT.DELETE,
        // danger: true,
        // divided: true,
        onClick: () => fns.loadDel?.(row),
      },
    ];

    const seen = new Set();
    const result = [];

    for (const a of candidates) {
      if (!a || !a.when) continue;

      const pass = allowByPerm(hasAuth, a.perm, row);
      const finalAction = pass ? a : applyDenyStrategy(a, denyStrategy);

      if (!finalAction) continue;
      if (seen.has(finalAction.key)) continue;
      seen.add(finalAction.key);
      result.push(finalAction);
    }

    result.sort((x, y) => (x.order ?? 0) - (y.order ?? 0));
    return result;
  };
}

/**
 * 一次性生成（可选导出）
 * @param {object} row
 * @param {object} options { hasAuth, fns, denyStrategy }
 */
export function buildNoticeActions(row, options = {}) {
  return createBuildNoticeActions(options)(row);
}

export default createBuildNoticeActions;
